package com.service.impl;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.common.dto.PagingReqDTO;
import com.config.exception.BussServiceException;
import com.dao.QuMapper;
import com.entity.Qu;
import com.entity.QuAnswer;
import com.entity.QuRepo;
import com.entity.dto.QuAnswerDTO;
import com.entity.dto.enums.QuType;
import com.entity.dto.ext.QuDetailDTO;
import com.entity.dto.request.QuQueryReqDTO;
import com.service.QuAnswerService;
import com.service.QuRepoService;
import com.service.QuService;
import com.service.RepoService;
import com.utils.PageUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 语言设置 服务实现类
 * </p>
 */
@Service
public class QuServiceImpl extends ServiceImpl<QuMapper, Qu> implements QuService {

    @Autowired
    private QuAnswerService quAnswerService;

    @Autowired
    private QuRepoService quRepoService;

    @Autowired
    private RepoService repoService;

    @Override
    public PageUtils paging(PagingReqDTO<QuQueryReqDTO> reqDTO) {
        Page page = new Page();
        page.setCurrent(reqDTO.getCurrent());
        page.setSize(reqDTO.getSize());


        int pagingCount = baseMapper.pagingCount(reqDTO.toPage());
        page.setTotal(pagingCount);
        if (pagingCount > 0) {
            List<Qu> paging = baseMapper.paging(reqDTO.toPage());
            page.setRecords(paging);
        } else {
            page.setRecords(Collections.emptyList());
        }
        return new PageUtils(page);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<String> ids) {
        // 移除题目
        this.deleteBatchIds(ids);

        // 移除选项
        EntityWrapper<QuAnswer> wrapper = new EntityWrapper<QuAnswer>();
        wrapper.in("qu_id", ids);
        quAnswerService.delete(wrapper);

        // 移除题库绑定
        EntityWrapper<QuRepo> quAnswerEntityWrapper = new EntityWrapper<QuRepo>();
        quAnswerEntityWrapper.in("qu_id", ids);
        quRepoService.delete(quAnswerEntityWrapper);
    }

    @Override
    public List<Qu> listByRandom(String repoId, Integer quType, List<String> excludes, Integer size) {
        return baseMapper.listByRandom(repoId, quType, excludes, size);
    }

    @Override
    public QuDetailDTO detail(String id) {

        QuDetailDTO respDTO = new QuDetailDTO();
        Qu qu = this.selectById(id);
        BeanUtils.copyProperties(qu, respDTO);

        List<QuAnswerDTO> answerList = quAnswerService.listByQu(id);
        respDTO.setAnswerList(answerList);

        List<String> repoIds = quRepoService.listByQu(id);
        respDTO.setRepoIds(repoIds);

        return respDTO;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(QuDetailDTO reqDTO) throws BussServiceException {


        // 校验数据
        this.checkData(reqDTO, "");

        Qu qu = new Qu();
        BeanUtils.copyProperties(reqDTO, qu);
        if (qu.getCreateTime() == null) {
            qu.setCreateTime(new Date());
        }
        qu.setUpdateTime(new Date());
        // 更新
        this.insertOrUpdate(qu);

        // 保存全部问题
        quAnswerService.saveAll(qu.getId(), reqDTO.getAnswerList());

        // 保存到题库
        quRepoService.saveAll(qu.getId(), qu.getQuType(), reqDTO.getRepoIds());

    }


    /**
     * 校验题目信息
     *
     * @param qu
     * @param no
     * @throws Exception
     */
    public void checkData(QuDetailDTO qu, String no) throws BussServiceException {


        if (StringUtils.isEmpty(qu.getContent())) {
            throw new BussServiceException("题目内容不能为空！");
        }


        if (CollectionUtils.isEmpty(qu.getRepoIds())) {
            throw new BussServiceException("至少要选择一个题库！");
        }

        List<QuAnswerDTO> answers = qu.getAnswerList();


        if (CollectionUtils.isEmpty(answers)) {
            throw new BussServiceException(no + "客观题至少要包含一个备选答案！");
        }


        int trueCount = 0;
        for (QuAnswerDTO a : answers) {

            if (a.getIsRight() == null) {
                throw new BussServiceException(no + "必须定义选项是否正确项！");
            }

            if (StringUtils.isEmpty(a.getContent())) {
                throw new BussServiceException(no + "选项内容不为空！");
            }

            if (a.getIsRight()) {
                trueCount += 1;
            }
        }

        if (trueCount == 0) {
            throw new BussServiceException(no + "至少要包含一个正确项！");
        }

        if (trueCount > 1 && qu.getQuType() == 4) {
            throw new BussServiceException(no + "最多包含一个正确项！");
        }


        //单选题
        if (qu.getQuType().equals(QuType.RADIO) && trueCount > 1) {
            throw new BussServiceException(no + "单选题不能包含多个正确项！");
        }

    }
}
